package br.com.mundodaprata.store.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;

@Entity
@Table(name = "orders")
public class Order extends AbstractEntity {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column
	private Long number;

	@ManyToOne
	@JoinColumn(name = "client")
	private Client client;

	@Temporal(TemporalType.DATE)
	@Column(nullable = false)
	private Date creation;

	@Column
	private double discount;

	@Column(name = "payment_form", nullable = false)
	private String paymentForm;

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "order")
	private List<OrderItem> items;

	public Long getNumber() {
		return number;
	}

	@Override
	public Long getCode() {
		return getNumber();
	}

	public void setNumber(Long number) {
		this.number = number;
	}

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}

	public Date getCreation() {
		return creation;
	}

	public void setCreation(Date creation) {
		this.creation = creation;
	}

	public double getDiscount() {
		return discount;
	}

	public void setDiscount(double discount) {
		this.discount = discount;
	}

	public String getPaymentForm() {
		return paymentForm;
	}

	public void setPaymentForm(String paymentForm) {
		this.paymentForm = paymentForm;
	}

	public List<OrderItem> getItems() {
		if (items == null) {
			items = new ArrayList<OrderItem>();
		}

		return items;
	}

	public void addItem(OrderItem item) {
		item.setOrder(this);
		getItems().add(item);
	}

	public void addItem(Product product, int quantity, double discount,
			double price) {
		OrderItem item = new OrderItem();
		item.setProduct(product);
		item.setOrder(this);
		item.setDiscount(discount);
		item.setQuantity(quantity);
		item.setPrice(price);

		addItem(item);
	}

	public void addItem(Product product) {
		addItem(product, 1, 0, product.getPrice());
	}

	public void addItem(Product product, int quantity, double discount) {
		addItem(product, quantity, discount, product.getPrice());
	}

	public Double getTotalValue() {
		double total = 0;
		List<OrderItem> items = getItems();

		for (OrderItem item : items) {
			total += item.getFinalPrice();
		}

		total -= total * (getDiscount() / 100);

		return total;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((number == null) ? 0 : number.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Order)) {
			return false;
		}
		Order other = (Order) obj;
		if (number == null) {
			if (other.number != null) {
				return false;
			}
		} else if (!number.equals(other.number)) {
			return false;
		}
		return true;
	}

	public static void main(String[] args) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("loja");
		EntityManager em = emf.createEntityManager();

		TypedQuery<Product> query = em.createNamedQuery("productByName",
				Product.class);

		query.setParameter("name", "BATERIA ASUS%".toUpperCase());

		List<Product> result = query.getResultList();

		Order order = new Order();
		order.setClient(em.find(Client.class, 28));
		order.setCreation(new Date());
		order.setDiscount(5);
		order.setPaymentForm("A VISTA");

		for (Product product : result) {
			order.addItem(product);
		}

		EntityTransaction transaction = em.getTransaction();

		try {
			transaction.begin();
			em.persist(order);
			transaction.commit();
		} catch (Exception e) {
			if (transaction.isActive()) {
				transaction.rollback();
			}
		}
	}

}